﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SharedGenomics.Core;
using SharedGenomics.Workbench.Presenters;  //needed for the reference to AnnotationWrapperPresenter. This is a bit untidy due to the circular namespace dependency but the wrapper is seemingly 
                                            //quite fundamental in the workbench now...

namespace SharedGenomics.Workbench.Core
{
    //NOTE: below are the presenters currently being wrapped...
    //GeneSummaryPresenter
    //NcbiSummaryPresenter
    //TextMinedPublicationsPresenter
    public class AnnotationWrapperPresenterInitialisationStage : PresenterInitialisationStage
    {
        private HashSet<Type> _presenterTypesToWrap;

        public AnnotationWrapperPresenterInitialisationStage()
        {
            this._presenterTypesToWrap = new HashSet<Type>();
        }

        public void WrapPresenter<T>() where T : IPresenter
        {
            this.WrapPresenter(typeof(T));
        }

        public void WrapPresenter(Type presenterType)
        {
            presenterType.ThrowIfNull("presenterType");
            ExceptionHelper.ThrowIf<ArgumentException>(!typeof(IPresenter).IsAssignableFrom(presenterType), "Type is not a presenter type");

            this._presenterTypesToWrap.Add(presenterType);
        }

        public override bool Initialise(IPresenterInitialisationContext context)
        {
            context.ThrowIfNull("context");
            context.Container.ThrowIfNull<ArgumentException>("Cannot create presenter - container not set on context");

            Type presenterType = context.PresenterType;
            IPresenter current = context.Current;
            if (current != null && presenterType != null && this._presenterTypesToWrap.Contains(presenterType))
            {
                //create new wrapper presenter and set the contained presenter to be the current presenter
                AnnotationWrapperPresenter wrapper = context.Container.Resolve<AnnotationWrapperPresenter>();
                wrapper.WrappedPresenter = current;

                context.Current = wrapper;
            }

            return true;
        }
    }
}
